import 'dart:async';
import 'dart:collection';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:ichinesereader/constants.dart';
import 'package:ichinesereader/controller/books.dart';
import 'package:ichinesereader/controller/cache.dart';
import 'package:ichinesereader/controller/user.dart';
import 'package:ichinesereader/models/student/assignmentSettings.dart';
//import 'package:ichinesereader/widgets/dialogs/recommendBookDialog.dart';
import 'package:universal_html/html.dart' as uHtml;
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import '../../utils/log.dart';
import 'bookQuizEditor.dart';

class BookForWebWebview extends StatefulWidget {
  const BookForWebWebview({
    Key? key,
    required this.bookId,
    this.bookCode,
    this.bookTitle,
    this.assignmentId,
    required this.readingType,
    this.userName,
  }) : super(key: key);
  final String bookId;
  final String? bookCode;
  final String? bookTitle;
  final String? assignmentId;
  final String? userName;
  final NanhaiBookReadingTypes readingType;
  static const String routeName = '/student/book';

  @override
  _BookForWebWebviewState createState() => _BookForWebWebviewState();
}

class _BookForWebWebviewState extends State<BookForWebWebview> {
  final GlobalKey webViewKey = GlobalKey();
  InAppWebViewController? webViewController;
  InAppWebViewSettings options = InAppWebViewSettings(
      useShouldOverrideUrlLoading: true,
      mediaPlaybackRequiresUserGesture: false,
      useHybridComposition: true,
      allowsInlineMediaPlayback: true,
      allowFileAccessFromFileURLs: true,
      allowUniversalAccessFromFileURLs: true,
      cacheEnabled: true,
      domStorageEnabled: true,
      javaScriptEnabled: true,
      allowsPictureInPictureMediaPlayback: true,
      enableViewportScale: true,
      disableLongPressContextMenuOnLinks: true,
      mixedContentMode: MixedContentMode.MIXED_CONTENT_ALWAYS_ALLOW);

  late PullToRefreshController pullToRefreshController;
  late ContextMenu contextMenu;

  final BooksController _booksController = Get.find();
  final UserController _userController = Get.find();
  final box = Hive.box('appconfig');
  AssignmentSettings _assignmentSettingsDto = new AssignmentSettings();
  AssignmentSettings _profileSettingsDto = new AssignmentSettings();
  bool updateProgress = false;
  late Timer periodicTimer;
  ValueNotifier valueNotifier = ValueNotifier(false);
  bool isFinished = false;

  @override
  void initState() {
    super.initState();
    if (box.get(CacheManagerKey['_quizAvailable'].toString())) {
      periodicTimer = Timer.periodic(
        const Duration(milliseconds: 2000),
        (timer) {
          // if already complete read before open book
          if (box.get(CacheManagerKey['_readComplete'].toString()) &&
              valueNotifier.value == false) {
            Future.delayed(const Duration(milliseconds: 3000), () {
              valueNotifier.value = true;
            });
            isFinished = true;
            timer.cancel();
          }
          // set valueNotifier.value = true till last page
          if (valueNotifier.value == false) {
            var currentPageNum = uHtml.window.localStorage['currentPageNum'];
            var totalPageNum = uHtml.window.localStorage['totalPageNum'];
            if (uHtml.window.localStorage['currentPageNum'] != null &&
                uHtml.window.localStorage['totalPageNum'] != '0' &&
                totalPageNum == currentPageNum) {
              Future.delayed(const Duration(milliseconds: 3000), () {
                valueNotifier.value = true;
              });
              isFinished = true;
              timer.cancel();
            }
          }
        },
      );
    } else {
      periodicTimer = Timer.periodic(
        const Duration(milliseconds: 2000),
        (timer) {
          if (box.get(CacheManagerKey['_readComplete'].toString())) {
            isFinished = true;
            timer.cancel();
          }
          if (isFinished == false) {
            var currentPageNum = uHtml.window.localStorage['currentPageNum'];
            var totalPageNum = uHtml.window.localStorage['totalPageNum'];
            if (uHtml.window.localStorage['currentPageNum'] != null &&
                uHtml.window.localStorage['totalPageNum'] != '0' &&
                totalPageNum == currentPageNum) {
              isFinished = true;
              timer.cancel();
            }
          }
        },
      );
    }

    if (widget.bookId != '') {
      _booksController.setCurrentBookId(widget.bookId.toString());
    }

    if (box.get(CacheManagerKey['nanhairole'].toString()) ==
            Constants.NanhaiRole_Student ||
        box.get(CacheManagerKey['nanhairole'].toString()) ==
            Constants.NanhaiRole_Individual) {
      updateProgress = true;
    }
    var settings = json.decode(
        box.get(CacheManagerKey['profilesettings'].toString()).toString());
    var _vocabulary = settings != null && settings['vocabulary'] != null
        ? settings['vocabulary']
        : true;
    if (widget.assignmentId != null && widget.assignmentId != '') {
      var assignmentSettings = _booksController.getCurrentAssignmentSettings();
      _assignmentSettingsDto.id = widget.assignmentId;
      if (assignmentSettings != null) {
        _assignmentSettingsDto.lang = assignmentSettings.lang;
        _assignmentSettingsDto.language = assignmentSettings.language;
        _assignmentSettingsDto.audio = assignmentSettings.audio;
        _assignmentSettingsDto.dictionary = assignmentSettings.dictionary;
        _assignmentSettingsDto.music = assignmentSettings.music;
        _assignmentSettingsDto.pinyin = assignmentSettings.pinyin;
        _assignmentSettingsDto.quizAudio = assignmentSettings.quizAudio;
      }
      uHtml.window.sessionStorage['assignmentId'] = '${widget.assignmentId}';
      uHtml.window.sessionStorage['assignmentSettings'] =
          '${assignmentSettingsToJson(_assignmentSettingsDto)}';
      uHtml.window.sessionStorage['vocabulary'] =
          _vocabulary ? 'true' : 'false';
    } else {
      uHtml.window.sessionStorage['assignmentId'] = '';
      uHtml.window.sessionStorage['assignmentSettings'] = '';
      _profileSettingsDto.lang = box.get('UserLang');
      _profileSettingsDto.language = box.get('UserLanguage');
      _profileSettingsDto.pinyin = box.get('UserPinyin');
      uHtml.window.sessionStorage['profileSettings'] =
          '${json.encode(_profileSettingsDto)}';
      uHtml.window.sessionStorage['vocabulary'] =
          _vocabulary ? 'true' : 'false';
    }

    pullToRefreshController = PullToRefreshController(
      onRefresh: () async {
        if (Platform.isAndroid) {
          webViewController?.reload();
        } else if (Platform.isIOS) {
          webViewController?.loadUrl(
              urlRequest: URLRequest(url: await webViewController?.getUrl()));
        }
      },
    );
  }

  @override
  void dispose() {
    super.dispose();
    periodicTimer.cancel();
  }

  @override
  Widget build(BuildContext context) {
    String _bookUrl = '${Constants.BaseURL}icr/student/book/${widget.bookId}';
    var myUserScripts = [
      UserScript(source: """window.updatePage = function (page, total) {
                  if(page == total){
                    console.log(true)}
                  }
                  """, injectionTime: UserScriptInjectionTime.AT_DOCUMENT_END),
    ];
    return Scaffold(
      resizeToAvoidBottomInset: true,
      floatingActionButton: ValueListenableBuilder(
        valueListenable: valueNotifier,
        builder: (context, value, child) {
          return Visibility(
              visible: value as bool && updateProgress,
              child: SizedBox(
                width: 45.0,
                height: 45.0,
                child: PointerInterceptor(
                  intercepting: true,
                  child: FloatingActionButton(
                    backgroundColor: Theme.of(context).primaryColorDark,
                    foregroundColor: Get.isDarkMode
                        ? Colors.black
                        : Theme.of(context).primaryColorLight,
                    heroTag: Text('bookquiz'),
                    tooltip: 'Book Quiz'.tr,
                    onPressed: () {
                      EasyLoading.show();
                      try {
                        Future.delayed(Duration(milliseconds: 1000), () {
                          // need exit the book here to avoid the quiz button still be shown on the book bar after failing quiz
                          Navigator.of(context).pop();
                          _booksController.updateBookStatus(
                              widget.bookId, widget.readingType);
                          _userController.refreshLevelPercentage();
                          Get.to(() => BookQuizEditor(
                                bookId: widget.bookId,
                                bookcode: widget.bookCode.toString(),
                                bookTitle: widget.bookTitle.toString(),
                                assignmentId: widget.assignmentId ?? null,
                              ));
                          // Navigator.pushNamed(context, '/student/quiz',
                          //     arguments: BookArguments(
                          //         widget.bookId,
                          //         widget.bookCode.toString(),
                          //         widget.bookTitle.toString(),
                          //         widget.assignmentId,
                          //         widget.readingType,
                          //         widget.userName));
                        });
                      } catch (error) {
                      } finally {
                        EasyLoading.dismiss();
                      }
                    },
                    child: Icon(
                      Icons.quiz_outlined,
                      size: 28,
                    ),
                    elevation: 5,
                    splashColor: Colors.grey,
                  ),
                ),
              ));
        },
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.miniEndTop,
      appBar: AppBar(
        title: Text(widget.bookTitle.toString()),
        leading: BackButton(
          onPressed: () {
            ////放在这里不准，读到最后一页再往前翻后退出这里仍然不是finished状态
            // var currentPageNum = uHtml.window.localStorage['currentPageNum'];
            // var totalPageNum = uHtml.window.localStorage['totalPageNum'];
            // if (uHtml.window.localStorage['currentPageNum'] != null &&
            //     totalPageNum == currentPageNum) {
            //   isFinished = true;
            // }
            // //这段代码可以直接来测试，不用读完书
            // Future.delayed(Duration(milliseconds: 50), () {
            //   _booksController
            //       .getRecommendedBookItems(widget.bookId)
            //       .then((items) {
            //     if (items.isNotEmpty) {
            //       showGeneralDialog(
            //           context: Get.context as BuildContext,
            //           transitionDuration: Duration(milliseconds: 400),
            //           pageBuilder: (bc, ania, anis) {
            //             return RecommendBookDialog(books: items);
            //           });
            //     }
            //   });
            // });
            if (isFinished && updateProgress) {
              _booksController.updateBookStatus(
                  widget.bookId, widget.readingType);
              // _userController.refreshLevelPercentage();
            }

            Future.delayed(Duration(milliseconds: 300), () {
              Navigator.of(context).pop();
            });

            // if (isFinished &&
            //     updateProgress &&
            //     !box.get(CacheManagerKey['_callEva']) &&
            //     (widget.assignmentId == null || widget.assignmentId == '')) {
            //   Future.delayed(Duration(milliseconds: 50), () {
            //     //Navigator.of(context).pop();
            //     _booksController
            //         .getRecommendedBookItems(widget.bookId)
            //         .then((items) {
            //       if (items.isNotEmpty) {
            //         showGeneralDialog(
            //             context: Get.context as BuildContext,
            //             transitionDuration: Duration(milliseconds: 400),
            //             pageBuilder: (bc, ania, anis) {
            //               return RecommendBookDialog(books: items);
            //             });
            //       }
            //     });
            //   });

            //   Future.delayed(Duration(milliseconds: 800), () {
            //     Navigator.of(context).pop();
            //   });
            // } else {
            //   // if (updateProgress == true) {
            //   //   _userController.refreshLevelPercentage();
            //   //   _booksController.updateBookStatus(
            //   //       widget.bookId, widget.readingType);
            //   // }
            //   Future.delayed(Duration(milliseconds: 800), () {
            //     Navigator.of(context).pop();
            //   });
            // }
          },
        ),
      ),
      body: SafeArea(
        child: Column(
          children: [
            Expanded(
              child: Stack(
                children: [
                  InAppWebView(
                    key: webViewKey,
                    initialUrlRequest: URLRequest(url: WebUri(_bookUrl)),
                    initialUserScripts:
                        UnmodifiableListView<UserScript>(myUserScripts),
                    initialSettings: options,
                    pullToRefreshController: pullToRefreshController,
                    onLoadStart: (controller, url) async {},
                    onWebViewCreated: (controller) async {
                      webViewController = controller;
                    },
                    onPermissionRequest: (controller, request) async {
                      return PermissionResponse(
                          resources: request.resources,
                          action: PermissionResponseAction.GRANT);
                    },
                    shouldOverrideUrlLoading:
                        (controller, navigationAction) async {
                      //var uri = navigationAction.request.url!;
                      // if (![
                      //   "http",
                      //   "https",
                      //   "file",
                      //   "chrome",
                      //   "data",
                      //   "javascript",
                      //   "about"
                      // ].contains(uri.scheme)) {
                      //   if (await canLaunchUrl(uri)) {
                      //     // Launch the App
                      //     await launchUrl(
                      //       uri,
                      //     );
                      //     // and cancel the request
                      //     return NavigationActionPolicy.CANCEL;
                      //   }
                      // }
                      return NavigationActionPolicy.ALLOW;
                    },
                    onLoadStop: (controller, url) async {},
                    onReceivedError: (controller, request, error) {
                      pullToRefreshController.endRefreshing();
                    },
                    onProgressChanged: (controller, progress) {
                      if (progress == 100) {
                        pullToRefreshController.endRefreshing();
                      }
                      setState(() {
                        //this.progress = progress / 100;
                        //urlController.text = this.url;
                      });
                    },
                    onUpdateVisitedHistory:
                        (controller, url, androidIsReload) {},
                    onConsoleMessage: (controller, consoleMessage) async {
                      Log.debug(consoleMessage.message);
                      Log.debug(consoleMessage.message == 'true');
                      if (consoleMessage.message == 'true') {
                        Future.delayed(const Duration(milliseconds: 4000), () {
                          _userController.refreshLevelPercentage();
                        });
                      }
                    },
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}
